import type ExecuteController from '../../lat-controller'

import type { TaskExecuteContext } from '../types'

import type { InterfaceHandler } from './index'

import HandlerLife from './life-handler'

abstract class BaseHandler<O, R> extends HandlerLife implements InterfaceHandler<O, R> {
  public nextHandler: InterfaceHandler<R, unknown> | null = null

  public prevHandler: InterfaceHandler<unknown, O> | null = null

  public executeController: ExecuteController | null = null

  public abstract handlerStatus: any

  public isFirstExecute = true

  public setExecuteController(executeController: ExecuteController): void {
    this.executeController = executeController
  }

  public linkHandler(nextHandler: InterfaceHandler<R, unknown>): void {
    if (this.nextHandler) {
      this.nextHandler.prevHandler = null
    }
    this.nextHandler = nextHandler
    nextHandler.prevHandler = this as unknown as InterfaceHandler<unknown, R>
  }

  public get isLastHandler(): boolean {
    return !this.nextHandler
  }

  public get isFirstHandler(): boolean {
    return !this.prevHandler
  }

  public abstract handle(original: O | null): void

  public forwardToHandler(result: R): void {
    if (this.nextHandler) {
      this.nextHandler.handle(result)
    }
  }

  public setHandlerStatus(status: any): void {
    this.handlerStatus = status
  }

  public equalHandlerStatus(status: any): boolean {
    return this.handlerStatus === status
  }

  public abstract execute(
    context: TaskExecuteContext,
  ): void

  public isHandleDataAcceptedComplete: boolean = false
}

export default BaseHandler
